//
// Created by denglibin on 2021/8/12.
//
/*客户区绘图设备DC，用来在非重绘的事件处理函数中使用，即除了EVT_PAINT和EVT_NC_PAINT事件之外的都可以
 * wxClientDC用来在非重绘事件处理函数中对窗口的客户区进行绘制。例如，如果你想作一个信
手涂鸦的程序，你可以在你的鼠标事件处理函数中创建一个wxClientDC。这个设备上下文也可以用
于擦除背景事件处理函数。

 */
#include <wx/app.h>
#include <wx/wx.h>
#include <wx/wxprec.h>
#include <string>
#include <wx/dcbuffer.h>
using namespace std;
/**
 * 窗体 frame
 * 使用wxClientDc 用鼠标绘图
 * 继承关系: wxObject<-wxDC<-wxWindowDC<-wxClientDC<-wxPaintDC
 */
class ClientDcFrame : public wxFrame
{
private:
    //声明事件表
    DECLARE_EVENT_TABLE();
    wxClientDC* dc = nullptr;
    wxPen pen;
    wxPoint lastPoint;
    bool first = true;

    /**
     * 绘制线
     * @param p
     */
    void DrawLine(const wxPoint p){
        if(this->first){
            this->lastPoint.x = p.x;
            this->lastPoint.y = p.y;
            this->first = false;
        }
        //dc->DrawPoint(p); //绘制点
        dc->DrawLine(this->lastPoint, p);
        this->lastPoint.x = p.x;
        this->lastPoint.y = p.y;
    }

    /**
     * 鼠标移动事件函数
     * @param event
     */
    void OnMotion(wxMouseEvent & event){
        if(event.Dragging()){
            auto p = event.GetPosition();
            this->DrawLine(p);

            //dc->SetPen(wxNullPen);
        }
    }
    /**
     * 左键点下
     * @param event
     */
    void OnLeftDown(wxMouseEvent& event){
        this->first = true;
        //cout << "left down" << endl;
    }

    /**
     * frame初始化
     */
    void initFrame(){
        //设置窗口位置
        wxPoint position;
        position.x = 300;
        position.y = 300;
        SetPosition(position);
        //设置背景色
        wxColour backGroundColor(0,100,0);
        this->SetBackgroundColour(backGroundColor);
        //设置宽高
        this->m_minWidth = 800;
        this->m_minHeight = 600;
    }
    void initClientDc(){
        this->dc = new wxClientDC(this);
        pen = (*wxYELLOW_PEN);
        pen.SetWidth(5); //宽度
        dc->SetPen(pen);
    }

public:
    explicit ClientDcFrame(wxString & title):wxFrame(nullptr, wxID_ANY, title){
        this->initFrame();
        this->initClientDc();
    }
    ~ClientDcFrame() override{
        delete this->dc;
    }
};
//事件和函数绑定
wxBEGIN_EVENT_TABLE(ClientDcFrame, wxFrame)
                EVT_MOTION(ClientDcFrame::OnMotion)
                EVT_LEFT_DOWN(ClientDcFrame::OnLeftDown)
wxEND_EVENT_TABLE()


/**
 * app
 */
class ClientDcApp:public wxApp
{
    bool OnInit()override
    {
        wxString title = wxT("wxClientDc绘制");
        auto * frame = new ClientDcFrame(title);
        frame->Show();
        return true;
    }
};


// 有了这一行就可以使用 OurApp& wxGetApp了()
DECLARE_APP(ClientDcApp)
//告诉主应用程序是哪个类wxWidgets（启动）
//IMPLEMENT_APP(ClientDcApp)


